package com.winning.zjjh.utils;

import org.apache.commons.lang.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.StandardHttpRequestRetryHandler;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HttpContext;

import javax.validation.constraints.NotNull;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author: xkh@winning.com.cn
 * @Desc: TODO
 * @Date: 2018-11-05 14:16
 **/
public class NetDataUtil {

    /**
     * 获取默认HttpClient实例
     *
     * @return HttpClient新实例
     */
    public static HttpClient getInstance() {
        return HttpClients.createDefault();
    }

    /**
     * 获取HttpClient实例
     *
     * @param httpClientConnectionManager http连接管理器 --参数（null->PoolingHttpClientConnectionManager）
     * @return httpClientConnectionManager实例
     */
    public static HttpClient getInstance(HttpClientConnectionManager httpClientConnectionManager) {
        HttpClientBuilder custom = HttpClients.custom();
        if (Objects.isNull(httpClientConnectionManager))
            custom.setConnectionManager(httpClientConnectionManager());
        else
            custom.setConnectionManager(httpClientConnectionManager);

        custom.setKeepAliveStrategy(new ConnectionKeepAliveStrategy() {
            @Override
            public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
                return 20 * 1000;
            }
        });

        custom.setRetryHandler(new StandardHttpRequestRetryHandler());
        return custom.build();
    }


    /**
     * 获取http get请求对象
     *
     * @return
     */
    public static HttpGet httpGet() {
        return new HttpGet();
    }

    /**
     * 获取http get请求对象根据自定义请求配置
     *
     * @param requestConfig 请求配置实例
     * @return
     */
    public static HttpGet httpGet(RequestConfig requestConfig) {
        HttpGet httpGet = new HttpGet();
        if (Objects.isNull(requestConfig))
            httpGet.setConfig(requestConfig());
        else
            httpGet.setConfig(requestConfig);

        return httpGet;
    }

    /**
     * 获取http post请求对象
     *
     * @return
     */
    public static HttpPost httpPost() {
        return new HttpPost();
    }

    /**
     * 获取http post请求对象根据自定义请求配置
     *
     * @param requestConfig 请求配置实例
     * @return
     */
    public static HttpPost httpPost(RequestConfig requestConfig) {
        HttpPost httpPost = new HttpPost();
        if (Objects.isNull(requestConfig))
            httpPost.setConfig(requestConfig());
        else
            httpPost.setConfig(requestConfig);

        httpPost.setHeader("Keep-Alive", "20");
        return httpPost;
    }


    /**
     * 获取模拟表单提交Entity
     *
     * @param nameValuePairs key,value对
     * @param chareset       字符编码，（可选）默认UTF-8
     * @return
     */
    public static UrlEncodedFormEntity urlEncodedFormEntity(Charset chareset, @NotNull NameValuePair... nameValuePairs) throws UnsupportedEncodingException {
        UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(Arrays.asList(nameValuePairs), chareset == null ? Consts.UTF_8 : chareset);
        return urlEncodedFormEntity;
    }

    /**
     * 获取参数实例
     *
     * @param name  参数名
     * @param value 参数值
     * @return
     */
    public static NameValuePair nameValuePair(@NotNull String name, @NotNull String value) {
        return new BasicNameValuePair(name, value);
    }

    private static RequestConfig requestConfig() {
        return RequestConfig.custom()
                .setSocketTimeout(1000 * 60 * 20)
                .setConnectTimeout(1000 * 60 * 2)
                .build();
    }

    private static HttpClientConnectionManager httpClientConnectionManager() {
        ConnectionSocketFactory connectionSocketFactory =
                PlainConnectionSocketFactory.getSocketFactory();
        LayeredConnectionSocketFactory layeredConnectionSocketFactory =
                SSLConnectionSocketFactory.getSocketFactory();
        Registry<ConnectionSocketFactory> registry =
                RegistryBuilder.<ConnectionSocketFactory>create()
                        .register("http", connectionSocketFactory)
                        .register("https", layeredConnectionSocketFactory)
                        .build();

        PoolingHttpClientConnectionManager poolingHttpClientConnectionManager =
                new PoolingHttpClientConnectionManager(registry);
        poolingHttpClientConnectionManager.setMaxTotal(500);
        poolingHttpClientConnectionManager.setDefaultMaxPerRoute(500);

        return poolingHttpClientConnectionManager;
    }

    /**
     * 获取数据下载的url
     *
     * @return
     */
    public static URI uri(String url) {

        if (StringUtils.isEmpty(url)) {
            return null;
        }
        try {
            return new URI(url);
        } catch (Exception e) {

        }

        return null;
    }


    /**
     * 获取当前的日期 yyyy-MM-dd HH:mm:ss
     *
     * @return
     */
    public static String currentDate() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return simpleDateFormat.format(new Date());
    }


    /**
     * 获取的日期 yyyy-MM-dd HH:mm:ss
     */
    public static String date(@NotNull Date date) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return simpleDateFormat.format(date);
    }


    /**
     * 分批次执行数据更新
     *
     * @param data  原始数据集
     * @param index 第n次执行更新（index参数值：（n-1），从0开始）
     * @param count 单次更新的数据标准条数
     * @return 单次执行数据更新的数据数量
     */
    public static List batchProcessData(List data, int index, int count) {
        List subdata = new ArrayList();
        int startIndex = index * count;
        int endIndex = (startIndex + count) > data.size() ? data.size() : (startIndex + count);
        for (int i = startIndex; i < endIndex; i++) {
            subdata.add(data.get(i));
        }
        return subdata;
    }
}
